/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servlet.edt;

import bdd.DBLink;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import src.IntervalCreneau;

/**
 *
 * @author boomar
 */
public class modifCrenau extends HttpServlet {

    public static final String DELETE_CRENAU = "DELETE FROM CRENEAU WHERE NUMSALLE = ? AND NUMENSEIGNANT = ? AND NUMTYPE = ? AND NUMEC = ? AND HORAIREDEBUT = ? AND HORAIREFIN = ? AND IDDATE = ? AND NUMPROMOTION = ?";
    public static final String INSERT_CRENAU = "INSERT INTO CRENEAU (NUMSALLE, NUMENSEIGNANT, NUMTYPE , NUMEC, HORAIREDEBUT, HORAIREFIN, IDDATE, NUMPROMOTION) VALUES (?,?,?,?,?,?,?,?)";
    public static final String DELETE_JOUR = "DELETE FROM JOURS WHERE IDDATE = ? AND NUMPROMOTION = ?";
    public static final String INSERT_JOUR = "INSERT INTO JOURS (IDDATE) VALUES (?)";
    public static final String SELECT_JOUR = "SELECT IDDATE FROM JOURS WHERE IDDATE = ?";
    public static final String SELECT_CRENAU = "SELECT * FROM CRENEAU WHERE NUMSALLE = ? AND NUMENSEIGNANT = ? AND NUMTYPE = ? AND NUMEC = ? AND HORAIREDEBUT = ? AND HORAIREFIN = ? AND IDDATE = ? AND NUMPROMOTION = ?";
    public static final String SELECT_CRENEAU_BIS = "SELECT * FROM CRENEAU WHERE IDDATE = ? AND NUMPROMOTION = ?";
    public String ec, type, jour, salle, enseignant, minuteDebut, minuteFin, dateDebut, dateFin, selectWeekDay;
    public String oldEc, oldType, oldJour, oldSalle, oldEnseignant, oldMinuteDebut, oldMinuteFin, oldDateDebut, oldDateFin, oldSelectWeekDay;
    public int heureDebut, heureFin, promotion;
    public int oldHeureDebut, oldHeureFin, oldPromotion;
    public boolean isInterval;
    public boolean withOlds = true;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        try {
            this.oldEc = (request.getParameter("oldEc") == null) ? "" : request.getParameter("oldEc");
            this.oldType = (request.getParameter("oldType") == null) ? "" : request.getParameter("oldType");
            this.oldJour = (request.getParameter("oldJour") == null) ? "" : request.getParameter("oldJour");
            this.oldSalle = (request.getParameter("oldSalle") == null) ? "" : request.getParameter("oldSalle");
            this.oldEnseignant = (request.getParameter("oldEnseignant") == null) ? "" : request.getParameter("oldEnseignant");
            this.oldHeureDebut = (request.getParameter("oldHeureDebut") == null || request.getParameter("oldHeureDebut").equals("")) ? 0 : Integer.parseInt(request.getParameter("oldHeureDebut"));
            this.oldMinuteDebut = (request.getParameter("oldMinuteDebut") == null || request.getParameter("oldMinuteDebut").equals("")) ? "00" : request.getParameter("oldMinuteDebut");
            this.oldHeureFin = (request.getParameter("oldHeureFin") == null || request.getParameter("oldHeureFin").equals("")) ? 0 : Integer.parseInt(request.getParameter("oldHeureFin"));
            this.oldMinuteFin = (request.getParameter("oldMinuteFin") == null || request.getParameter("oldMinuteFin").equals("")) ? "00" : request.getParameter("oldMinuteFin");
            this.oldPromotion = (request.getParameter("oldPromotion") == null || request.getParameter("oldPromotion").equals("")) ? 0 : Integer.parseInt(request.getParameter("oldPromotion"));

            this.ec = (request.getParameter("ec") == null) ? "" : request.getParameter("ec");
            this.type = (request.getParameter("type") == null) ? "" : request.getParameter("type");
            this.jour = (request.getParameter("jour") == null) ? "" : request.getParameter("jour");
            this.salle = (request.getParameter("salle") == null) ? "" : request.getParameter("salle");
            this.enseignant = (request.getParameter("enseignant") == null) ? "" : request.getParameter("enseignant");
            this.heureDebut = (request.getParameter("heureDebut") == null || request.getParameter("heureDebut").equals("")) ? 0 : Integer.parseInt(request.getParameter("heureDebut"));
            this.minuteDebut = (request.getParameter("minuteDebut") == null || request.getParameter("minuteDebut").equals("")) ? "00" : request.getParameter("minuteDebut");
            this.heureFin = (request.getParameter("heureFin") == null || request.getParameter("heureFin").equals("")) ? 0 : Integer.parseInt(request.getParameter("heureFin"));
            this.minuteFin = (request.getParameter("minuteFin") == null || request.getParameter("minuteFin").equals("")) ? "00" : request.getParameter("minuteFin");
            this.promotion = (request.getParameter("promotion") == null || request.getParameter("promotion").equals("")) ? 0 : Integer.parseInt(request.getParameter("promotion"));
            this.isInterval = (request.getParameter("minuteFin") == null) ? false : Boolean.parseBoolean(request.getParameter("isInterval"));
            this.dateDebut = (request.getParameter("dateDebut") == null || request.getParameter("dateDebut").equals("")) ? "00" : request.getParameter("dateDebut");
            this.dateFin = (request.getParameter("dateFin") == null || request.getParameter("dateFin").equals("")) ? "00" : request.getParameter("dateFin");
            this.selectWeekDay = (request.getParameter("selectWeekDay") == null) ? "" : request.getParameter("selectWeekDay");

            if (oldEc.equals("")
                    || oldType.equals("")
                    || oldJour.equals("")
                    || oldSalle.equals("")
                    || oldEnseignant.equals("")
                    || (oldHeureDebut == 0 && oldMinuteDebut.equals("00"))
                    || (oldHeureFin == 0 && oldMinuteFin.equals("00"))
                    || ((oldHeureDebut * 60) + Integer.parseInt(oldMinuteDebut)) >= ((oldHeureFin * 60) + Integer.parseInt(oldMinuteFin))
                    || oldPromotion == 0) {
                out.println("<p> <font color=\"red\"> Données incomplètes pour la suppression de l'ancien créneau</font> </p>");
                withOlds = true;
            }

            if (ec.equals("")
                    || type.equals("")
                    || (jour.equals("") && (dateDebut.equals("") && dateFin.equals("") && selectWeekDay.equals("")))
                    || salle.equals("")
                    || enseignant.equals("")
                    || (heureDebut == 0 && minuteDebut.equals("00"))
                    || (heureFin == 0 && minuteFin.equals("00"))
                    || promotion == 0) {
                out.println("<p> <font color=\"red\"> Impossible de soummetre la demande \n Tous les champs sont obligatoires  </font> </p>");
                return;
            }

            if (((heureDebut * 60) + Integer.parseInt(minuteDebut)) >= ((heureFin * 60) + Integer.parseInt(minuteFin))) {
                out.println("<p> <font color=\"red\"> Impossible de soummetre la demande \n L'heure du début ne peut être suppérieure à celle de la fin </font> </p>");
                return;
            }

            alterCrenau(out, request);
        } catch (Exception e) {
            e.printStackTrace(out);
            out.println("<p> <font color=\"red\"> Suite à un problèmem technique, vote demande ne peut être traitée </font> </p>");
            out.println("<p> Détails : " + e.getMessage() + "</p>");
        } finally {
            out.close();
        }
    }

    protected void alterCrenau(PrintWriter out, HttpServletRequest request) {
        try {
            if (isInterval == true) {
                String[] sDateDebut = dateDebut.split("/");
                String[] sDateFin = dateFin.split("/");

                Date oDateDebut = new Date(Integer.parseInt(sDateDebut[2]), Integer.parseInt(sDateDebut[1]), Integer.parseInt(sDateDebut[0]));
                Date oDateFin = new Date(Integer.parseInt(sDateFin[2]), Integer.parseInt(sDateFin[1]), Integer.parseInt(sDateFin[0]));

                if (oDateDebut.after(oDateFin)) {
                    out.println("<p> <font color=\"red\"> Impossible de soummetre la demande \n La date du début ne peut être suppérieure à celle de la fin </font> </p>");
                    return;
                }

                SimpleDateFormat formatterDate = new SimpleDateFormat("dd/MM/yy");
                String tmpJour;
                for (Date leJour : getDaysInRange(oDateDebut, oDateFin, selectWeekDay)) {
                    tmpJour = formatterDate.format(leJour) + " 00:00:00,000000000";
                    if (withOlds == true) {
                        deleteOldCrenau(out, tmpJour, formatterDate.format(leJour)); //On supprime l'ancien crénau s'il existe dans le jour 'leJour'
                    }
                    insertCreneau(tmpJour, out, formatterDate.format(leJour));
                }
            } else {
                String jourToPrint = jour;
                jour += " 00:00:00,000000000";
                insertCreneau(jour, out, jourToPrint);
            }
        } catch (Exception e) {
            e.printStackTrace(out);
            out.println("<p> <font color=\"red\"> Suite à un problèmem technique, vote demande ne peut être traitée </font> </p>");
            out.println("<p> Détails : " + e.getMessage() + "</p>");
        }
    }

    public void insertCreneau(String leJour, PrintWriter out, String jourToPrint) throws SQLException {
        ArrayList<IntervalCreneau> listCreneau = getCreneauJour(leJour, out);
        IntervalCreneau intervalCreneau = new IntervalCreneau(Integer.parseInt(heureDebut + minuteDebut), Integer.parseInt(heureFin + minuteFin));

        for (IntervalCreneau tmpIntervalCreneau : listCreneau) {
            if (intervalCreneau.intersects(tmpIntervalCreneau)) {
                out.println("<p> <font color=\"orange\"> Attention : Suite à un chevauchement entre le nouveau et un ancien créneau le : " + jourToPrint + " de " + heureDebut + "h" + minuteDebut + " à " + heureFin + "h" + minuteFin + " il va y avoir remplacement</font> </p>");
                deleteIntersectCrenau(out, leJour, tmpIntervalCreneau.getLeft(), tmpIntervalCreneau.getRight(), jourToPrint); //Cas chevauchement => on écrase
            }
        }

//        if (intervalCreneau.intersects(listCreneau)) {
//            out.println("<p> <font color=\"orange\"> Attention : Suite à un chevauchement entre le nouveau et un ancien créneau le : " + leJour.substring(0, 8) + " de " + heureDebut + "h" + minuteDebut + " à " + heureFin + "h" + minuteFin + " il va y avoir remplacement</font> </p>");
//            deleteCrenauIfExists(out, leJour); //Si un créneau existant on écrase
//        }

        DBLink dbLink = new DBLink();
        dbLink.connexion();

        dbLink.setPst(dbLink.getConnection().prepareStatement(SELECT_JOUR));
        dbLink.getPst().setString(1, leJour);
        dbLink.setRs(dbLink.getPst().executeQuery());

        if (dbLink.getRs().next() == false) {
            dbLink.setPst(dbLink.getConnection().prepareStatement(INSERT_JOUR));
            dbLink.getPst().setString(1, leJour);
            dbLink.getPst().executeQuery();
        }

        dbLink.setPst(dbLink.getConnection().prepareStatement(SELECT_CRENAU));
        dbLink.getPst().setString(1, salle);
        dbLink.getPst().setString(2, enseignant);
        dbLink.getPst().setString(3, type);
        dbLink.getPst().setString(4, ec);
        dbLink.getPst().setString(5, heureDebut + "" + minuteDebut);
        dbLink.getPst().setString(6, heureFin + "" + minuteFin);
        dbLink.getPst().setString(7, leJour);
        dbLink.getPst().setString(8, Integer.toString(promotion));
        dbLink.setRs(dbLink.getPst().executeQuery());



        if (dbLink.getRs().next() == false) {
            dbLink.setPst(dbLink.getConnection().prepareStatement(INSERT_CRENAU));
            dbLink.getPst().setString(1, salle);
            dbLink.getPst().setString(2, enseignant);
            dbLink.getPst().setString(3, type);
            dbLink.getPst().setString(4, ec);
            dbLink.getPst().setString(5, heureDebut + "" + minuteDebut);
            dbLink.getPst().setString(6, heureFin + "" + minuteFin);
            dbLink.getPst().setString(7, leJour);
            dbLink.getPst().setString(8, Integer.toString(promotion));
            dbLink.getPst().executeQuery();


        } else {
            out.println("<p> Le crénau existe déjà pour le jour :" + jourToPrint + " </p>");
            return;
        }

        out.println("<p> <font color=\"green\"> Le nouveau crénau a bien été enregistré pour le " + jourToPrint + " de " + heureDebut + "h" + minuteDebut + " à " + heureFin + "h" + minuteFin + "</font> </p>");
    }

    public ArrayList<IntervalCreneau> getCreneauJour(String leJour, PrintWriter out) {

        try {
            ArrayList<IntervalCreneau> listCreneau = new ArrayList<IntervalCreneau>();
            DBLink dbLink = new DBLink();
            dbLink.connexion();

            dbLink.setPst(dbLink.getConnection().prepareStatement(SELECT_CRENEAU_BIS));
            dbLink.getPst().setString(1, leJour);
            dbLink.getPst().setString(2, Integer.toString(promotion));
            dbLink.setRs(dbLink.getPst().executeQuery());

            while (dbLink.getRs().next()) {
                listCreneau.add(new IntervalCreneau(dbLink.getRs().getInt("HORAIREDEBUT"),
                        dbLink.getRs().getInt("HORAIREFIN")));
            }
            return listCreneau;
        } catch (Exception e) {
            e.printStackTrace(out);
            out.println("<p> <font color=\"red\"> Suite à un problème technique, vote demande ne peut être traitée </font> </p>");
            out.println("<p> Détails : " + e.getMessage() + "</p>");
            return null;
        }
    }

    public ArrayList<Date> getDaysInRange(Date strdate, Date enddate, String dayName) throws ParseException {

        ArrayList<Date> dates = new ArrayList<Date>();

        SimpleDateFormat formatterDay = new SimpleDateFormat("EEEE");

        Calendar ss = Calendar.getInstance();
        Calendar ee = Calendar.getInstance();

        ss.setTime(strdate);
        ee.setTime(enddate);

        ee.add(Calendar.DATE, 1);

        String day = "";

        while (!ss.equals(ee)) {
            day = formatterDay.format(ss.getTime());
            if (day.equals(dayName)) {
                dates.add(ss.getTime());
            }
            ss.add(Calendar.DATE, 1);
        }
        return dates;
    }

    protected void deleteIntersectCrenau(PrintWriter out, String leJour, int horaireDebut, int horaireFin, String jourToPrint) {
        try {
            DBLink dbLink = new DBLink();
            dbLink.connexion();

            dbLink.setPst(dbLink.getConnection().prepareStatement(DELETE_CRENAU));
            dbLink.getPst().setString(1, salle);
            dbLink.getPst().setString(2, enseignant);
            dbLink.getPst().setString(3, type);
            dbLink.getPst().setString(4, ec);
            dbLink.getPst().setInt(5, horaireDebut);
            dbLink.getPst().setInt(6, horaireFin);
            dbLink.getPst().setString(7, leJour);
            dbLink.getPst().setString(8, Integer.toString(promotion));
            dbLink.getPst().executeQuery();

            String sDebut = Integer.toString(horaireDebut);
            String hDebut = sDebut.substring(0, sDebut.length() == 3 ? 1 : 2);
            String mDebut = sDebut.substring(hDebut.length(), sDebut.length());

            String sFin = Integer.toString(horaireFin);
            String hFin = sFin.substring(0, sFin.length() == 3 ? 1 : 2);
            String mFin = sFin.substring(hFin.length(), sFin.length());

            out.println("<p> <font color=\"green\"> Suppression réussie du crénau le : " + jourToPrint + " de " + hDebut + "h" + mDebut + " à " + hFin + "h" + mFin + "</font> </p>");

        } catch (Exception e) {
            e.printStackTrace(out);
            out.println("<p> <font color=\"red\"> Suite à un problèmem technique, vote demande ne peut être traitée </font> </p>");
            out.println("<p> Détails : " + e.getMessage() + "</p>");
        }
    }

    protected void deleteCrenauIfExists(PrintWriter out, String leJour) {
        try {
            DBLink dbLink = new DBLink();
            dbLink.connexion();

            dbLink.setPst(dbLink.getConnection().prepareStatement(DELETE_CRENAU));
            dbLink.getPst().setString(1, salle);
            dbLink.getPst().setString(2, enseignant);
            dbLink.getPst().setString(3, type);
            dbLink.getPst().setString(4, ec);
            dbLink.getPst().setString(5, heureDebut + "" + minuteDebut);
            dbLink.getPst().setString(6, heureFin + "" + minuteFin);
            dbLink.getPst().setString(7, leJour);
            dbLink.getPst().setString(8, Integer.toString(promotion));
            dbLink.getPst().executeQuery();

            out.println("<p> <font color=\"green\"> Suppression réussie du crénau le : " + leJour.substring(0, 8) + " de " + heureDebut + "h" + minuteDebut + " à " + heureFin + "h" + minuteFin + "</font> </p>");

        } catch (Exception e) {
            e.printStackTrace(out);
            out.println("<p> <font color=\"red\"> Suite à un problèmem technique, vote demande ne peut être traitée </font> </p>");
            out.println("<p> Détails : " + e.getMessage() + "</p>");
        }
    }

    protected void deleteOldCrenau(PrintWriter out, String leJour, String jourToPrint) {
        try {
            DBLink dbLink = new DBLink();
            dbLink.connexion();

            dbLink.setPst(dbLink.getConnection().prepareStatement(DELETE_CRENAU));
            dbLink.getPst().setString(1, oldSalle);
            dbLink.getPst().setString(2, oldEnseignant);
            dbLink.getPst().setString(3, oldType);
            dbLink.getPst().setString(4, oldEc);
            dbLink.getPst().setString(5, oldHeureDebut + "" + oldMinuteDebut);
            dbLink.getPst().setString(6, oldHeureFin + "" + oldMinuteFin);
            dbLink.getPst().setString(7, leJour);
            dbLink.getPst().setString(8, Integer.toString(oldPromotion));
            dbLink.getPst().executeQuery();

            out.println("<p> <font color=\"green\"> L'ancien crénau a bien été supprimé le " + jourToPrint + " de " + oldHeureDebut + "h" + oldMinuteDebut + " à " + oldHeureFin + "h" + oldMinuteFin + "</font> </p>");

        } catch (Exception e) {
            e.printStackTrace(out);
            out.println("<p> <font color=\"red\"> Suite à un problèmem technique, vote demande ne peut être traitée </font> </p>");
            out.println("<p> Détails : " + e.getMessage() + "</p>");
        }
    }

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);


    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);


    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";

    }// </editor-fold>
}
